infercnv results exploration
for SCPCS000179subdiagnosis <- readr::read_tsv(
file.path("..", "..", "..", "data", "current", params$scpca_project_id, "single_cell_metadata.tsv"),
show_col_types = FALSE
) |>
dplyr::filter(scpca_sample_id == params$sample_id) |>
dplyr::pull(subdiagnosis)This notebook explores using infercnv
to estimate tumor and normal cells in SCPCS000179 from SCPCP000006. This
sample has a(n) Anaplastic subdiagnosis.
infercnv was run using the 06_inferCNV.R
script with and without a normal reference, from the same patient or
from an inter-patient pull of normal cells. We tested the impact of the
sub-selection of normal cells using either immune, and/or endothelial
cells as healthy reference. In addition, we are exploring the use of the
HMM
based CNV Prediction Methods.
infercnv currently support two models for HMM-based CNV
prediction, what we refer to as the i3 and i6 models. These are set in
the ‘infercnv::run()’ as HMM_type=‘i3’ or HMM_type=‘i6’ (i6 is default).
Each method operates on the ‘preliminary infercnv object’ which has been
processed through the standard inferCNV processing routines, involving
subtraction of signal corresponding to ‘normal (reference)’ cells and
smoothing operations.
i3 HMM is a three-state CNV model representing deletion, neutral, and amplification states.
i6 HMM: a six-state CNV model that predicts the following CNV levels:
Of note, running infercnv with a i6 HMM model is very
long, ~2hours of running time per sample, while i3 HMM model only
requires ~10min per sample.
In this notebook, we want to compare the heatmaps of CNV profiles, and evaluate how comparable are the methods and how sensible they are to key parameters such as selection of healthy reference.
Here we defined function that will be used multiple time all along the notebook.
For a Seurat object object, the function
Do_CNV_heatmap load the infercnv object
created with the script 06_infercnv.R using
reference_value as a reference and call the function
SCpubr::do_CopyNumberVariantPlot to plot the mean CNV score
in each group defined in group.by.
object is the Seurat object
infercnv_obj is the infercnv
object
group.by is the metadata used for grouping the
violin plots
reference_value indicates the reference used for
infercnv, either endothelial, immune, both or
pool.
Do_CNV_heatmap <- function(object, infercnv_obj, group.by, reference_value){
out <- SCpubr::do_CopyNumberVariantPlot(sample = object,
infercnv_object = infercnv_obj,
using_metacells = FALSE,
chromosome_locations = SCpubr::human_chr_locations,
return_object = FALSE,
group.by = group.by
)
out <- out +
ggtitle(glue::glue("Copy Number Variant Plot, ", reference_value)) +
ylab(label = "")
return(out)
}For a Seurat object an infercnv object
created with the script 06_infercnv.R using
reference_value as a reference, the function
Do_CNV_score calculate a CNV score per cell. The score is
calculated based on the biostar discussion. The
function Do_CNV_score returns the Seurat
object with an additional metadata named
CNV-score_{reference_value}.
reference_value is the selection of normal cells used
for infercnvseurat_object and infercnv_obj are the
Seuratand infercnv object created with the
script 06_infercnv.RFor a Seurat object objectand a metadata
metadata, the function visualize_metadata will
plot FeaturePlot and BarPlot
object is the Seurat object
meta the gene or quantitative value to be
plotted
group.by is the metadata used for grouping the
violin plots
visualize_metadata <- function(object, meta, group.by){
if(is.numeric(object@meta.data[,meta])){
d <- SCpubr::do_FeaturePlot(object,
features = meta,
pt.size = 0.2,
legend.width = 0.5,
legend.length = 5,
legend.position = "right") + ggtitle(meta)
b <- SCpubr::do_ViolinPlot(object,
features = meta,
ncol = 1,
group.by = group.by,
legend.position = "none")
return(d + b + plot_layout(ncol = 2, widths = c(2,4)))
}
else{
d <- SCpubr::do_DimPlot(object, reduction="umap", group.by = group.by, label = TRUE, repel = TRUE) + ggtitle(paste0(meta," - umap")) + theme(text=element_text(size=18))
b <- SCpubr::do_BarPlot(sample = object,
group.by = meta,
split.by = group.by,
position = "fill",
font.size = 10,
legend.ncol = 3) +
ggtitle("% cells")+
xlab(print(group.by)) +
theme(text=element_text(size=18))
return(d + b + plot_layout(ncol = 2, widths = c(2,4)))
}
}For a Seurat object objectand a features
features, the function visualize_feature will
plot FeaturePlot and ViolinPlot
object is the Seurat object
feature the gene or quantitative value to be
plotted
group.by is the metadata used for grouping the
violin plots
visualize_feature <- function(object, feature, group.by ){
d <- SCpubr::do_FeaturePlot(object,
features = feature,
pt.size = 0.2,
legend.width = 0.5,
legend.length = 5,
legend.position = "right") + ggtitle(as.character(feature))
b <- SCpubr::do_ViolinPlot(object,
features = feature,
ncol = 1,
group.by = group.by,
legend.position = "none",
assay = "SCT") + ylab(as.character(feature))
return(d + b + plot_layout(ncol = 2, widths = c(2,4)))
}For a Seurat object objectand a features
features, the function visualize_feature will
plot FeaturePlot and ViolinPlot
object is the Seurat object
features the gene or quantitative value to be
plotted
group.by is the metadata used for grouping the
violin plots
infercnv HMM cnv
predictionThe wrapper_explore_hmm take as input the
infercnv_obj generated with infercnv HMM cnv
predictions. The wrapper allows the following steps and plots:
For each chromosome, we look at the repartition of the
proportion_cnv_ in cells labeled as immune, endothelial,
stroma and fetal nephron. proportion_cnv_ is the proportion
in number of genes that are part of any cnv/loss/duplication in the
given chr.
For each chromosome, we look at the distribution of the
proportion_cnv_ in cells labeled as immune, endothelial,
stroma and fetal nephron. proportion_cnv_ is the proportion
in number of genes that are part of any cnv/loss/duplication in the
given chr.
We are quite confident that immune and endothelial cells are well
identified by label transfer done in
02b_label-transfer_fetal_kidney_reference_Stewart.Rmd. The
distribution of CNV for endothelial and immune cells should thus be a
single peak center on 0.
We do not know if fetal nephron and stroma cells are a mix of normal and cancer cells. Would they be a group of normal cells, we should expect a single peak center on 0 for every chromosome. As we expect to have a large number of cancer with heterogeneous CNV, we should see multiple peaks.
The Dotplot representation summarizes the percentage of
cells in each compartment with cnv in each of the 22 chromosomes.
Finally, we try to calculate single CNV score and assess its potential in identifying cells with CNV versus normal cells without CNV.
We simply checked for each chromosome if the cell
has_cnv_chr. Would the cell have more than
cnv_threshold chromosome with CNV, the global
has_cnv_score will be TRUE. Else, the cell will have a
has_cnv_score set to FALSE.
wrapper_explore_hmm <- function(infercnv_obj, cnv_threshold = 1){
p <- list()
#### Plot UMAP of known Wilms tumor related alteration
p[["compartment"]] <- visualize_metadata(infercnv_obj, "fetal_kidney_predicted.compartment", "seurat_clusters")
#### Feature plot and repartition of the CNV per chromosome
for(i in 1:22){
tmp1 <- visualize_feature(infercnv_obj, feature=glue::glue("proportion_cnv_chr", i), group.by = "fetal_kidney_predicted.compartment")
tmp2 <- visualize_density(infercnv_obj, features=glue::glue("proportion_cnv_chr", i), group.by = "fetal_kidney_predicted.compartment")
p[[glue::glue("proportion_cnv_chr", i)]] <- tmp1 + tmp2 + plot_layout(ncol = 3, widths = c(1,2,2))
}
#### DotPlot
p[["Dotplot"]] <- DotPlot(infercnv_obj, features = colnames(infercnv_obj@meta.data)[grepl("has_cnv_chr", colnames(infercnv_obj@meta.data))], group.by = "fetal_kidney_predicted.compartment", assay = "SCT") +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
#### CNV score
meta <- infercnv_obj@meta.data
meta$has_cnv_score <- rowSums(meta[,grepl("has_cnv_chr", colnames(meta))])
meta$has_cnv_score[meta$has_cnv_score > cnv_threshold] <- "CNV"
# we know that some immune cells might have false positive CNV
meta$has_cnv_score[meta$has_cnv_score %in% c(0:cnv_threshold)] <- "no CNV"
infercnv_obj <- AddMetaData(infercnv_obj, meta$has_cnv_score, col.name = "has_cnv_score")
p[["infercnv_obj"]] <- infercnv_obj
p[["cnv_seurat"]] <- visualize_metadata(infercnv_obj, "has_cnv_score", "seurat_clusters")
p[["cnv_compartment"]] <- visualize_metadata(infercnv_obj, "has_cnv_score", "fetal_kidney_predicted.compartment")
return(p)
}The input for this notebook are the results of
06_inferCNV.R
Here we plot the output of infercnv as heatmaps of CNV.
We first look at the png file generated by the infercnv
function. We then used the infercnv object to look at mean
CNV value across compartments (immune, endothelial, stroma and fetal
nephron).
infercnv_obj <- list()
for(reference_value in c("reference-none", "reference-immune", "reference-endothelium", "reference-both")){
infercnv_obj[[reference_value]] <- readRDS(file.path(result_dir, glue::glue(reference_value, "_HMM-no") , glue::glue("06_infercnv_", params$sample_id, "_", reference_value, "_HMM-no.rds")))
print(Do_CNV_heatmap(object = srat, infercnv_obj = infercnv_obj[[reference_value]], group.by = "fetal_kidney_predicted.compartment", reference_value = reference_value))
}
These heatmaps emphasize the importance of the selection of normal cells
prior the inference of CNV. The normal reference should contain as much
cell types as possible, in order to minimize false positive CNV. In our
case, we should take immune and entodethial cells when possible.
Of note: By default if no reference is provided,
infercnv take the mean of expression as normal reference.
The risk is that the main cell population (in our case the fetal nephron
compartment) might be mistaken as the normal baseline.
We want to calculate a single CNV score and asess if/how it can be use to define cells with CNV versus stable/normal cells. We defined the score as discribed in the biostar discussion.
We would expect:
immune and endothelial cells to have a low CNV score
fetal nephron and stroma cells to have low to high CNV score.
Ideally, the CNV score distribution should show two peaks, one for the normal cells with no CNV, one for cancer cells with more genomic rearrangements.
for(reference_value in c("reference-none", "reference-immune", "reference-endothelium", "reference-both")){
srat <- Do_CNV_score(srat,infercnv_obj = infercnv_obj[[reference_value]], reference_value)
p1 <- visualize_feature(srat, feature = glue::glue("CNV-score_", reference_value) , group.by = "fetal_kidney_predicted.compartment" )
p2 <- visualize_density(srat, features=glue::glue("CNV-score_", reference_value), group.by = "fetal_kidney_predicted.compartment")
print(p1 + p2 + plot_layout(ncol = 3, widths = c(1,2,2)))
}This unique CNV score does not look promising. We will not use this score in future notebooks.
We might have to select chromosomes we would like to look at, i.e. the one relevant for Wilms tumor (1p, 1q, chr17).
We then explore infercnv results generated with immune and endothelial cells as reference, using a HMM-i3 prediction models.
We load the Seurat object generated in
06_infercnv.R
#### Load the `Seurat` object
srat_i3 <- readRDS(file.path(module_base, "results", params$sample_id, glue::glue("06_infercnv_HMM-i3_", params$sample_id, "_reference-both.rds")))and explore the CNV results using the
wrapper_explore_hmm fucntion.
## [1] "seurat_clusters"
## [1] "seurat_clusters"
## [1] "fetal_kidney_predicted.compartment"
## $compartment
##
## $proportion_cnv_chr1
##
## $proportion_cnv_chr2
##
## $proportion_cnv_chr3
##
## $proportion_cnv_chr4
##
## $proportion_cnv_chr5
##
## $proportion_cnv_chr6
##
## $proportion_cnv_chr7
##
## $proportion_cnv_chr8
##
## $proportion_cnv_chr9
##
## $proportion_cnv_chr10
##
## $proportion_cnv_chr11
##
## $proportion_cnv_chr12
##
## $proportion_cnv_chr13
##
## $proportion_cnv_chr14
##
## $proportion_cnv_chr15
##
## $proportion_cnv_chr16
##
## $proportion_cnv_chr17
##
## $proportion_cnv_chr18
##
## $proportion_cnv_chr19
##
## $proportion_cnv_chr20
##
## $proportion_cnv_chr21
##
## $proportion_cnv_chr22
##
## $Dotplot
##
## $infercnv_obj
## An object of class Seurat
## 88749 features across 6358 samples within 2 assays
## Active assay: RNA (60319 features, 0 variable features)
## 1 layer present: counts
## 1 other assay present: SCT
## 2 dimensional reductions calculated: pca, umap
##
## $cnv_seurat
##
## $cnv_compartment
We then explore infercnv results generated with immune
and endothelial cells as reference, using a HMM-i6
model.
We load the Seurat object generated in
06_infercnv.R
srat_i6 <- readRDS(file.path(module_base, "results", params$sample_id, glue::glue("06_infercnv_HMM-i6_", params$sample_id, "_reference-both.rds")))## [1] "seurat_clusters"
## [1] "seurat_clusters"
## [1] "fetal_kidney_predicted.compartment"
## $compartment
##
## $proportion_cnv_chr1
##
## $proportion_cnv_chr2
##
## $proportion_cnv_chr3
##
## $proportion_cnv_chr4
##
## $proportion_cnv_chr5
##
## $proportion_cnv_chr6
##
## $proportion_cnv_chr7
##
## $proportion_cnv_chr8
##
## $proportion_cnv_chr9
##
## $proportion_cnv_chr10
##
## $proportion_cnv_chr11
##
## $proportion_cnv_chr12
##
## $proportion_cnv_chr13
##
## $proportion_cnv_chr14
##
## $proportion_cnv_chr15
##
## $proportion_cnv_chr16
##
## $proportion_cnv_chr17
##
## $proportion_cnv_chr18
##
## $proportion_cnv_chr19
##
## $proportion_cnv_chr20
##
## $proportion_cnv_chr21
##
## $proportion_cnv_chr22
##
## $Dotplot
##
## $infercnv_obj
## An object of class Seurat
## 88749 features across 6358 samples within 2 assays
## Active assay: RNA (60319 features, 0 variable features)
## 1 layer present: counts
## 1 other assay present: SCT
## 2 dimensional reductions calculated: pca, umap
##
## $cnv_seurat
##
## $cnv_compartment
We lastly explore infercnv results generated with a pull
of immune and endothelial cells from different Wilms tumor samples as
reference, using a HMM-i3 prediction model.
The selection of normal cells to be spiked-in as a normal reference
prior running infercnv has been performed in
`06b_build-normal-cell_reference.R. We selected samples that haven’t
been pre-treated with chemotherapies. Indeed, even if normal cells
shouldn’t be affected by chemotherapy in terms of CNV, we are not sure
how chemotherapies can affect the CNV profile of normal cells. We thus
decided to only take endothelial and immune cells from non-treated
samples whose label transfer scores are greater than 0.85 to build the
reference of normal cells.
Seurat objectWe load the Seurat object generated in
06_infercnv.R and transfer the infercnv
metadata to the main Seurat object of sample SCPCS000179
saved in 02b-fetal_kidney_label-transfer_SCPCS000179.Rds.
Such a transfer is required as the merged Seurat object
+ spike-in cells does not contained the umap reduction.
seurat_full <- readRDS(file.path(module_base, "results", params$sample_id, glue::glue("06_infercnv_HMM-i3_", params$sample_id, "_reference-pull.rds")))
# subset non spike-in cells
keep_cells <- colnames(srat)
seurat <- subset(seurat_full, cells = keep_cells)
meta <- seurat@meta.data[colnames(srat),]
# merge the new info into the srat metadata
srat_pull <- AddMetaData(srat, meta[,grepl("_cnv_chr", colnames(meta))], col.name = colnames(meta[grepl("_cnv_chr", colnames(meta))]))## [1] "seurat_clusters"
## [1] "seurat_clusters"
## [1] "fetal_kidney_predicted.compartment"
## $compartment
##
## $proportion_cnv_chr1
##
## $proportion_cnv_chr2
##
## $proportion_cnv_chr3
##
## $proportion_cnv_chr4
##
## $proportion_cnv_chr5
##
## $proportion_cnv_chr6
##
## $proportion_cnv_chr7
##
## $proportion_cnv_chr8
##
## $proportion_cnv_chr9
##
## $proportion_cnv_chr10
##
## $proportion_cnv_chr11
##
## $proportion_cnv_chr12
##
## $proportion_cnv_chr13
##
## $proportion_cnv_chr14
##
## $proportion_cnv_chr15
##
## $proportion_cnv_chr16
##
## $proportion_cnv_chr17
##
## $proportion_cnv_chr18
##
## $proportion_cnv_chr19
##
## $proportion_cnv_chr20
##
## $proportion_cnv_chr21
##
## $proportion_cnv_chr22
##
## $Dotplot
##
## $infercnv_obj
## An object of class Seurat
## 88749 features across 6358 samples within 2 assays
## Active assay: RNA (60319 features, 0 variable features)
## 1 layer present: counts
## 1 other assay present: SCT
## 2 dimensional reductions calculated: pca, umap
##
## $cnv_seurat
##
## $cnv_compartment
We compare here the binary CNV scores calculated with the three HMM prediction models:
HMM-i3 with inter-patient endothelial and immunce cells as reference
HMM-i3 with intra-patient endothelial and immunce cells as reference
HMM-i6 with intra-patient endothelial and immunce cells as reference
p1 <- SCpubr::do_DimPlot(pull$infercnv_obj, "has_cnv_score", plot.title = "inter-patient reference, HMM-i3", reduction = "umap")
p2 <- SCpubr::do_DimPlot(p$infercnv_obj, "has_cnv_score", plot.title = "intra-patient reference, HMM-i3", reduction = "umap")
p3 <- SCpubr::do_DimPlot(q$infercnv_obj, "has_cnv_score", plot.title = "intra-patient reference, HMM-i6", reduction = "umap")
p1 + p2 + p3 + plot_layout(ncol = 3)We should run infercnv with the most diverse normal
reference as possible, including different cell types. Providing no
reference is not a good option, as we think that most of the cells are
cancer cells with few CNV. In our case, we advise taking at least immune
and endothelial cells as normal reference.
The HMM prediction models help exploring the
infercnv results. In this notebook, we have compared three
HMM prediction models:
HMM-i3 with inter-patient endothelial and immunce cells as reference
HMM-i3 with intra-patient endothelial and immunce cells as reference
HMM-i6 with intra-patient endothelial and immunce cells as reference
Globally, the three scores seems to drive similar conclusions, with the majority of fetal nephron and stroma cells being cancer cells, at least in the sample selected.
The HMM-i3 model with inter-patient endothelial and immunce cells as reference has the advantage to be usable for all Wilms tumor samples, including the ones with a very low number of immune and/or endothelial cells.
The HMM-i3 model with intra-patient endothelial and immunce cells as reference seems to be the cleaner, ~fast to run (10 minutes per samples) and is more precise than the HMM-i3 with the inter-patient reference.
The HMM-i6 model with intra-patient endothelial and immunce cells as reference is very slow (~2 hours per sample) and couldn’t be used for the entire cohorte. It is more noisy than the i3 version. However, it could have the potential to detect cancer cells with very low CNV profile.
Surprisingly, running infercnv with emdothelial and
immune cells from (i) the same patient or (ii) a set of Wilms tumor
patients do not seem to affect drastically the results. Some false
positive CNV might occur in every patient due to the inter-patient
variability. By comparing the results in conditions (i) and (ii), we
should be able to understand which false positive are recurrent and do
not take them into account.
# record the versions of the packages used in this analysis and other environment information
sessionInfo()## R version 4.4.1 (2024-06-14)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 22.04.4 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so; LAPACK version 3.10.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8
## [6] LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Europe/Vienna
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] Seurat_5.1.0 SeuratObject_5.0.2 sp_2.1-4 patchwork_1.2.0 ggplot2_3.5.1 SCpubr_2.0.2 infercnv_1.20.0
##
## loaded via a namespace (and not attached):
## [1] RcppAnnoy_0.0.22 splines_4.4.1 later_1.3.2 ggplotify_0.1.2 bitops_1.0-8
## [6] tibble_3.2.1 polyclip_1.10-7 fastDummies_1.7.4 lifecycle_1.0.4 fastcluster_1.2.6
## [11] edgeR_4.2.1 doParallel_1.0.17 rprojroot_2.0.4 globals_0.16.3 lattice_0.22-6
## [16] vroom_1.6.5 MASS_7.3-61 ggdist_3.3.2 magrittr_2.0.3 limma_3.60.4
## [21] plotly_4.10.4 sass_0.4.9 rmarkdown_2.28 jquerylib_0.1.4 yaml_2.3.10
## [26] httpuv_1.6.15 sctransform_0.4.1 spam_2.10-0 spatstat.sparse_3.1-0 reticulate_1.38.0
## [31] cowplot_1.1.3 pbapply_1.7-2 RColorBrewer_1.1-3 multcomp_1.4-26 abind_1.4-5
## [36] zlibbioc_1.50.0 Rtsne_0.17 GenomicRanges_1.56.1 purrr_1.0.2 BiocGenerics_0.50.0
## [41] yulab.utils_0.1.7 TH.data_1.1-2 sandwich_3.1-1 GenomeInfoDbData_1.2.12 IRanges_2.38.1
## [46] S4Vectors_0.42.1 ggrepel_0.9.5 irlba_2.3.5.1 listenv_0.9.1 spatstat.utils_3.1-0
## [51] goftest_1.2-3 RSpectra_0.16-2 spatstat.random_3.3-1 fitdistrplus_1.2-1 parallelly_1.38.0
## [56] coin_1.4-3 leiden_0.4.3.1 codetools_0.2-20 DelayedArray_0.30.1 tidyselect_1.2.1
## [61] futile.logger_1.4.3 farver_2.1.2 UCSC.utils_1.0.0 viridis_0.6.5 rjags_4-16
## [66] matrixStats_1.3.0 stats4_4.4.1 spatstat.explore_3.3-2 jsonlite_1.8.8 progressr_0.14.0
## [71] ggridges_0.5.6 survival_3.7-0 iterators_1.0.14 foreach_1.5.2 tools_4.4.1
## [76] ica_1.0-3 Rcpp_1.0.13 glue_1.7.0 gridExtra_2.3 SparseArray_1.4.8
## [81] xfun_0.47 distributional_0.5.0 MatrixGenerics_1.16.0 GenomeInfoDb_1.40.1 dplyr_1.1.4
## [86] withr_3.0.1 formatR_1.14 fastmap_1.2.0 fansi_1.0.6 caTools_1.18.2
## [91] digest_0.6.37 gridGraphics_0.5-1 parallelDist_0.2.6 R6_2.5.1 mime_0.12
## [96] colorspace_2.1-1 scattermore_1.2 gtools_3.9.5 tensor_1.5 spatstat.data_3.1-2
## [101] utf8_1.2.4 tidyr_1.3.1 generics_0.1.3 data.table_1.16.0 httr_1.4.7
## [106] htmlwidgets_1.6.4 S4Arrays_1.4.1 uwot_0.2.2 pkgconfig_2.0.3 gtable_0.3.5
## [111] modeltools_0.2-23 lmtest_0.9-40 SingleCellExperiment_1.26.0 XVector_0.44.0 htmltools_0.5.8.1
## [116] dotCall64_1.1-1 scales_1.3.0 Biobase_2.64.0 png_0.1-8 phyclust_0.1-34
## [121] spatstat.univar_3.0-0 knitr_1.48 lambda.r_1.2.4 rstudioapi_0.16.0 tzdb_0.4.0
## [126] reshape2_1.4.4 coda_0.19-4.1 nlme_3.1-166 cachem_1.1.0 zoo_1.8-12
## [131] stringr_1.5.1 KernSmooth_2.23-24 libcoin_1.0-10 parallel_4.4.1 miniUI_0.1.1.1
## [136] pillar_1.9.0 grid_4.4.1 vctrs_0.6.5 gplots_3.1.3.1 RANN_2.6.2
## [141] promises_1.3.0 xtable_1.8-4 cluster_2.1.6 evaluate_0.24.0 readr_2.1.5
## [146] locfit_1.5-9.10 mvtnorm_1.3-1 cli_3.6.3 compiler_4.4.1 futile.options_1.0.1
## [151] rlang_1.1.4 crayon_1.5.3 future.apply_1.11.2 labeling_0.4.3 forcats_1.0.0
## [156] argparse_2.2.3 plyr_1.8.9 fs_1.6.4 stringi_1.8.4 viridisLite_0.4.2
## [161] deldir_2.0-4 assertthat_0.2.1 munsell_0.5.1 lazyeval_0.2.2 spatstat.geom_3.3-2
## [166] Matrix_1.7-0 RcppHNSW_0.6.0 hms_1.1.3 bit64_4.0.5 future_1.34.0
## [171] statmod_1.5.0 shiny_1.9.1 highr_0.11 SummarizedExperiment_1.34.0 ROCR_1.0-11
## [176] igraph_2.0.3 RcppParallel_5.1.9 bslib_0.8.0 bit_4.0.5 ape_5.8